#include "daemon_runner.h"

static bool is_running = false;
static void sig_exit(int sig)
{
    is_running = false;
}

gate_status_t daemon_runner_check_process(sub_process_t *process);
void daemon_runner_run(void)
{
    is_running = true;
    // 参数1: 切换到根目录 参数2:关闭 标准输入 标准输出 错误输出
    daemon(0, 1);

    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

    // 把 标准输入 标准输出 错误输出 重定向
    open("/dev/null", O_RDWR); // 标准输入 重定向
    open("/root/gateway.log", O_RDWR | O_CREAT | O_APPEND, 0644);
    open("/root/gateway.log", O_RDWR | O_CREAT | O_APPEND, 0644);

    signal(SIGINT, sig_exit);  // ctrl+c
    signal(SIGTERM, sig_exit); // kill 进程id   (不能使用-9)

    sub_process_t app_process = {
        .path = "/usr/bin/gateway",
        .args = "app",
        .pid = -1};

    sub_process_t ots_process = {
        .path = "/usr/bin/gateway",
        .args = "ota",
        .pid = -1};

    while (is_running)
    {
        daemon_runner_check_process(&app_process);
        daemon_runner_check_process(&ots_process);
        sleep(2);
    }
}

gate_status_t daemon_runner_check_process(sub_process_t *process)
{
    int status;
    if (process->pid > 0) // 进程曾经启动过
    {
        pid_t pid = waitpid(process->pid, &status, WNOHANG);
        if (pid == 0) // 整个参数WNOHANG 并且进程还或者, 则返回0
        {
            log_debug("process %s %s is running", process->path, process->args);
            return OK;
        }
        else if (pid > 0)
        {
            log_debug("process %s %s is not running", process->path, process->args);
        }
        else if (pid < 0)
        {
            /* code */
            log_error("process %s %s waitpid error", process->path, process->args);
        }
    }
    process->pid = -1;
    pid_t pid = fork();
    if (pid > 0)
    {
        // 在父进程中执行, pid就是子进程的id
        process->pid = pid;
    }
    else if (pid == 0)
    {
        // 在子进程中执行
        log_debug("process %s %s start", process->path, process->args);
        execl(process->path, process->path, process->args, NULL);

        perror("execl error");
        return ERROR;
    }
    else if (pid < 0)
    {
        perror("fork error");
        return ERROR;
    }

    // 启动子进程
    return OK;

    //
}
